package gitee

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"

	"gitee.com/yazutang/go-oauth2/config"
)

// gitee第三方认证客户信息
type OAuthClient struct {
	ClientId     string
	ClientSecret string
	RedirectUrl  string
}

/*
{
    "access_token": "f5c4dd877f3858fb51b5a295777e1caf",
    "token_type": "bearer",
    "expires_in": 86400,
    "refresh_token": "9274b67cae04f15f369db1869ddc8304d381f7fad5f68f0e221f9e29529c008f",
    "scope": "user_info",
    "created_at": 1637658746
}
*/
// 根据授权码获取到的Token信息
type TokenResult struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	Scope        string `json:"scope"`
	CreatedAt    int    `json:"created_at"`
}

func NewOAuthClient() *OAuthClient {
	return &OAuthClient{
		ClientId:     config.Conf.GetString("OAUTH.CLIENT_ID"),
		ClientSecret: config.Conf.GetString("OAUTH.CLIENT_SECRET"),
		RedirectUrl:  config.Conf.GetString("OAUTH.REDIRECT_URL"),
	}
}

func NewTokenResult() *TokenResult {
	return &TokenResult{}
}

var client = NewOAuthClient()

func GetTokenResult(code string) (*TokenResult, error) {
	// 怎么发送POST请求
	// https://appdividend.com/2019/12/02/golang-http-example-get-post-http-requests-in-golang/

	reqData, err := json.Marshal(map[string]string{
		"grant_type":    "authorization_code",
		"code":          code,
		"client_id":     client.ClientId,
		"client_secret": client.ClientSecret,
		"redirect_uri":  client.RedirectUrl,
	})

	if err != nil {
		return nil, err
	}

	resp, err := http.Post("https://gitee.com/oauth/token", "application/json", bytes.NewBuffer(reqData))

	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)

	if err != nil {
		return nil, err
	}

	tokenResult := NewTokenResult()

	err = json.Unmarshal(data, tokenResult)

	if err != nil {
		return nil, err
	}

	return tokenResult, nil
}

func GetAccessToken(code string) (string, error) {
	tokenResult, err := GetTokenResult(code)
	if err != nil {
		return "", err
	}
	return tokenResult.AccessToken, nil
}
